﻿namespace TagBasedResourceManagePlatform.Database
{
    using System;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity;
    using System.Linq;
    using System.Text;
    using System.Data.Entity.ModelConfiguration;
    using System.Collections.Generic;

    public class DatabaseContext : DbContext
    {
        //您的上下文已配置为从您的应用程序的配置文件(App.config 或 Web.config)
        //使用“DatabaseContext”连接字符串。默认情况下，此连接字符串针对您的 LocalDb 实例上的
        //“TagBasedResourceManagePlatform.Database.DatabaseContext”数据库。
        // 
        //如果您想要针对其他数据库和/或数据库提供程序，请在应用程序配置文件中修改“DatabaseContext”
        //连接字符串。
        public DatabaseContext()
            : base("name=DatabaseContext")
        {
        }

        //为您要在模型中包含的每种实体类型都添加 DbSet。有关配置和使用 Code First  模型
        //的详细信息，请参阅 http://go.microsoft.com/fwlink/?LinkId=390109。

        public virtual DbSet<Setting> Settings { get; set; }
        public virtual DbSet<Resource> Resources { get; set; }
        public virtual DbSet<ResourceTag> ResourceTags { get; set; }
        public virtual DbSet<Album> Albums { get; set; }
        public virtual DbSet<AlbumTags> AlbumTags { get; set; }
        public virtual DbSet<Project> Projects { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<Album>().HasMany<Resource>(T => T.Resources).WithMany().Map(
                TMap =>
                {
                    TMap.MapLeftKey("AlbumId");
                    TMap.MapRightKey("ResourceId");
                    TMap.ToTable("AlbumResource");
                });

            modelBuilder.Entity<Project>().HasMany<Resource>(T => T.Resources).WithMany().Map(
                TMap =>
                {
                    TMap.MapLeftKey("ProjectId");
                    TMap.MapRightKey("ResourceId");
                    TMap.ToTable("ProjectResource");
                });

            modelBuilder.Entity<Project>().HasMany<Album>(T => T.Albums).WithMany().Map(
                TMap =>
                {
                    TMap.MapLeftKey("ProjectId");
                    TMap.MapRightKey("AlbumId");
                    TMap.ToTable("ProjectAlbum");
                });
        }
    }
    
    public enum ResourceType : int
    {
        File = 1,
        Folder = 2
    }

    public enum AccessLevel : int
    {
        Any = 1,
        Friend = 2,
        OnlySelf = 3
    }

    [Table("ResourceTags")]
    public class ResourceTag
    {
        [Key, Required, DatabaseGenerated(DatabaseGeneratedOption.None), ForeignKey("Resource")]
        public int ResourceId { get; set; }
        public virtual Resource Resource { get; set; }
        [Required]
        public string Tags { get; set; }
    }

    [Table("AlbumTags")]
    public class AlbumTags
    {
        [Key, Required, DatabaseGenerated(DatabaseGeneratedOption.None), ForeignKey("Album")]
        public int AlbumId { get; set; }
        public virtual Album Album { get; set; }
        [Required]
        public string Tags { get; set; }
    }

    [Table("Resources")]
    public class Resource
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Resource()
        {
        }

        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        [MaxLength(64), Required]
        public string Title { get; set; }

        [MaxLength(256), Required]
        public string Summary { get; set; }

        [Required]
        public string Description { get; set; }

        public int? ThumbnailId { get; set; } = -1;

        [Required]
        public ResourceType Type { get; set; }

        [Required]
        public AccessLevel AccessLevel { get; set; } = AccessLevel.Any;

        [Required]
        public DateTime CreateTime { get; set; }

        [Required]
        public int Ranks { get; set; } = 5;

        [Required]
        public int TotalViewCount { get; set; }

        [Required,MaxLength(2048)]
        public string PhysicalPath { get; set; }

        [Required,MaxLength(256)]
        public string FileName { get; set; }

        [NotMapped()]
        public Misc.MineTypeHelper.MineType MineType {
            get
            {
                return new Misc.MineTypeHelper.MineType()
                {
                    MajorType = MineTypeMajor,
                    MinorType = MineTypeMinor
                };
            }
            set
            {
                MineTypeMajor = value.MajorType;
                MineTypeMinor = value.MinorType;
            }
        }

        [Required, MaxLength(32)]
        public string MineTypeMajor { get; set; }
        [Required, MaxLength(32)]
        public string MineTypeMinor { get; set; }

        [Required]
        public int MStorageId { get; set; } = -1;

        [Required,MaxLength(260)]
        public string MD5 { get; set; }
        [Required]
        public string Tags { get; set; }
    }

    [Table("Albums")]
    public class Album
    { 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Album()
        {
            Resources = new HashSet<Resource>();
        }

        [Key]
        public int Id { get; set; }

        [Required, MaxLength(64)]
        public string Title { get; set; }

        [Required, MaxLength(256)]
        public string Summary { get; set; }

        [Required]
        public string Description { get; set; }

        public int? ThumbnailId { get; set; } = -1;

        [Required]
        public AccessLevel AccessLevel { get; set; } = AccessLevel.Any;

        [Required]
        public DateTime CreateTime { get; set; }

        [Required]
        public DateTime ModifyTime { get; set; }

        [Required]
        public string Tags { get; set; }

        public virtual ICollection<Resource> Resources { get; set; }
    }

    [Table("Projects")]
    public class Project
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Project()
        {
            Resources = new HashSet<Resource>();
            Albums = new HashSet<Album>();
        }

        [Key]
        public int Id { get; set; }

        [Required, MaxLength(64)]
        public string Title { get; set; }

        [Required, MaxLength(256)]
        public string Summary { get; set; }

        [Required]
        public string Description { get; set; }

        public int? ThumbnailId { get; set; } = -1;

        [Required]
        public AccessLevel AccessLevel { get; set; } = AccessLevel.Any;

        [Required]
        public DateTime CreateTime { get; set; }

        [Required]
        public DateTime ModifyTime { get; set; }

        [Required]
        public string Tags { get; set; }

        public virtual ICollection<Resource> Resources { get; set; }
        public virtual ICollection<Album> Albums { get; set; }
    }

    [Table("Settings")]
    public class Setting
    {
        [Key, MaxLength(256), Required]
        public string Name { get; set; }

        [Required]
        public string Value { get; set; }
    }
}